﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using System.Net.Mail;
using System.Net;
using System.Security.Cryptography;
using System.Net.Security;
using System.Data;
using System.Configuration;



using ElCharro01.Manager;
using ElCharro01.Models;

namespace ElCharro01.Controllers
{
    public class AccountController : Controller
    {
        private Entities db = new Entities();
        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }
        UserManager UserManager = new UserManager();

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

            base.Initialize(requestContext);
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ValidateUser(model.UserName, model.Password))
                {
                    Session["UserId"] = db.UserSet.Single(u => u.Username == model.UserName).ID;
                    AssociateCart();
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("InitializedIndex", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "L'Username e/o La Password Forniti Non Sono Corretti.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            FormsService.SignOut();
            Session["UserId"] = 0;
            Session["cartId"] = 0;
            return RedirectToAction("Index", "Home");
        }

        // **************************************
        // URL: /Account/Register
        // **************************************

        public ActionResult Register()
        {
            //passo la lista degli user per poterla utilizzare nel textbox a completamento
            ViewBag.UserList = db.UserSet.ToList();
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    FormsService.SignIn(model.UserName, false /* createPersistentCookie */);

                    /* Creazione Utente */


                    ElCharro01.Models.Customer Customer = new ElCharro01.Models.Customer();
                    {
                        Customer.Username = model.UserName;
                        Customer.Password = model.Password;
                        Customer.Email = model.Email;
                        Customer.Bonus = 0;
                        Customer.DomandaSegreta = model.DomandaSegreta;
                        Customer.RispostaSegreta = model.RispostaSegreta;

                        if (model.Reclutatore != null && db.UserSet.Where(u => u.Username == model.Reclutatore).Count() == 1)
                            Customer.Reclutatore = db.UserSet.Single(u => u.Username == model.Reclutatore);
                        
                        //compilo i dati relativi al customer

                        Customer.Nome = model.Nome;
                        Customer.Cognome = model.Cognome;
                        Customer.Cellulare = model.Cellulare;
                        Customer.TelefonoFisso = model.TelefonoFisso;
                        
                        db.UserSet.AddObject(Customer);
                        db.SaveChanges();

                    }

                    //associo il ruolo "User" al nuovo utente registrato
                    aspnet_Users asp_user = db.aspnet_Users.Single(u => u.UserName == model.UserName);
                    vw_aspnet_UsersInRoles userInRoles = new vw_aspnet_UsersInRoles();

                    //per poter associare il roleid devo creare un System.Guid
                    System.Guid sysGuid = new Guid("fa431426-5d48-49a3-ae4d-5bf1660effa3");

                    userInRoles.RoleId = sysGuid;
                    userInRoles.UserId = asp_user.UserId;
                    db.vw_aspnet_UsersInRoles.AddObject(userInRoles);
                    db.SaveChanges();

                    /* Creazione Location */
                    ElCharro01.Models.Location Location = new ElCharro01.Models.Location();
                    {
                        Location.Nazione = model.Nazione;
                        Location.Citta = model.Citta;
                        Location.Indirizzo = model.Indirizzo;
                        Location.CodicePostale = model.CAP;
                        Location.Customer = Customer;
                        Location.Nome = model.NomeLocazione;
                        db.LocationSet.AddObject(Location);
                        db.SaveChanges();
 
                    }
                    Session["UserId"] = Customer.ID;
                    //gestisco il carrello dell'utente , vedi funzione per maggiori informazioni
                    AssociateCart();
                    return RedirectToAction("InitializedIndex", "Home");
                }
                else
                {
                    ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View(model);
        }

        // **************************************
        // URL: /Account/ChangePassword
        // **************************************

        [Authorize]
        public ActionResult ChangePassword()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword))
                {
                    int userId = (int)Session["UserId"];
                    User user = db.UserSet.Single(u => u.ID == userId);
                    user.Password = model.ConfirmPassword;
                    db.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);
                    db.SaveChanges();
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View(model);
        }

        // **************************************
        // URL: /Account/ChangePasswordSuccess
        // **************************************

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        public ActionResult RecoverAccount()
        {
            return View();
        }
        public ActionResult RecoverAccountByUsername()
        {
            return View();
        }

        public ActionResult RecoverAccountByEmail()
        {
            return View();
        }
        [HttpPost]
        public ActionResult RecoverAccountByEmail(string email)
        {
            bool succeded;

            //se per qualche motivo non va a buon fine il recupero pass viene laciata un'eccezione
            try
            {
                User user = db.UserSet.Single(u => u.Email == email);
                if (user != null)
                {
                    succeded = UserManager.SendResetPasswordMail(user.ID);
                }
                else
                {
                    succeded = false;
                }

            }

            catch (Exception ex)
            {
                succeded = false;
            }

            if (succeded)
            {
                return RedirectToAction("GetPasswordSuccess");
            }
            else
            {
                ModelState.AddModelError("", "L'Email inserita non è valida, riprovare.");
            }

            return View();
        }

        //recupero acount tramite inserimento dell'username. Verrà inviata una nuova password autogenrata
        [HttpPost]
        public ActionResult RecoverAccountByUsername(string username)
        {
            bool succeded ;

            //se per qualche motivo non va a buon fine il recupero pass viene laciata un'eccezione
             try
                {
                    User user = db.UserSet.Single(u => u.Username == username);
                    if (user != null)
                    {

                        succeded = UserManager.SendResetPasswordMail(user.ID);
                    }
                    else
                    {
                        succeded = false;
                    }

                }

             catch (Exception ex)
             {
                 succeded = false;
             }

             if (succeded)
             {
                 return RedirectToAction("GetPasswordSuccess");
             }
             else
             {
                 ModelState.AddModelError("", "L'Email inserita non è valida, riprovare.");
             }

            return View();
        }
       
        //comunico l'avvenuta spedizione della password via mail
        public ActionResult GetPasswordSuccess()
        {
            return View();
        }

        public void AssociateCart()
        {
            Customer customer = new Customer();
            int id = (int)Session["UserId"];
            customer = (Customer)db.UserSet.Single(c => c.ID == id);
            int CartId = (int)Session["cartId"];
            //se l'utente non ha riempito il carrello viene caricato il carrello riempito nell'ultima sessione
            if (CartId == 0 && customer.Cart != null)
                Session["cartId"] = customer.Cart.Id;

            ///se l'utente ha riempito il carrello viene associo all'utente il carrello che ha creato, cancellando un eventuale carrello già esistente
            else if (CartId != 0 && customer.Cart != null)
            {
                db.CartSet.DeleteObject(customer.Cart);   // cancello il vecchio carrello
                db.SaveChanges();
                customer.Cart = db.CartSet.Single(c => c.Id == CartId);
                db.SaveChanges();
            }
            ///caso in cui l'utente non ha alcun carrello associato da una vecchia sessione di navigazione sul sito
            else if (CartId != 0 && customer.Cart == null)
            {
                customer.Cart = db.CartSet.Single(c => c.Id == CartId);
                db.SaveChanges();
            }
           
        }

    }
}
